package com.slipper.system.message.service;

import java.util.Arrays;
import java.util.List;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.slipper.constants.Constants;
import com.slipper.system.message.bo.MessageBO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;

import com.slipper.system.message.dao.MessageStatusDao;
import com.slipper.system.message.bo.MessageStatusBO;

import com.slipper.core.transaction.ReadTransactional;
import com.slipper.core.transaction.WriteTransactional;
import com.slipper.util.Tool;
import com.slipper.util.UUID;

@Service
@ReadTransactional
public class MessageStatusService {
    @Resource
    private MessageStatusDao messageStatusDao;
    
    public MessageStatusBO queryBy(String id) {
        return messageStatusDao.queryBy(id);
    }
    
    public List<MessageStatusBO> queryList(MessageStatusBO bo) {
        return messageStatusDao.queryList(bo);
    }
    
    public PageInfo<MessageStatusBO> queryPage(MessageStatusBO bo) {
        PageHelper.startPage(bo.getPageNumber(), bo.getPageSize());
        return new PageInfo<>(messageStatusDao.queryList(bo));
    }
    
    @WriteTransactional
    public int save(MessageStatusBO bo) {
        if (Tool.isNotBlank(bo.getId())) {
            return messageStatusDao.update(bo);
        } else {
            bo.setId(UUID.getUUID());
            return messageStatusDao.insert(bo);
        }
    }

    @WriteTransactional
    public int save(String messageId, String receiverIds) {
        if (Tool.isBlank(messageId)) return 0;
        MessageStatusBO bo = new MessageStatusBO();
        bo.setMessageId(messageId);
        List<MessageStatusBO> statusList = queryList(bo);

        if (Tool.isBlank(receiverIds)) {
            statusList.forEach(status -> messageStatusDao.delete(status));
        } else {
            List<String> receiverIdList = Arrays.asList(receiverIds.split(","));
            statusList.stream()
                    .filter(status -> receiverIdList.stream().noneMatch(id -> (status.getOrganizationId() + "@" + status.getEmployeeId()).equals(id)))
                    .forEach(status -> messageStatusDao.delete(status));

            receiverIdList.stream()
                    .filter(id -> statusList.stream().noneMatch(status -> (status.getOrganizationId() + "@" + status.getEmployeeId()).equals(id)))
                    .forEach(id -> {
                        MessageStatusBO status = new MessageStatusBO();
                        status.setId(UUID.getUUID());
                        status.setMessageId(messageId);
                        if (id.contains("@")) {
                            status.setOrganizationId(id.split("@")[0]);
                            status.setEmployeeId(id.split("@")[1]);
                        } else {
                            status.setEmployeeId(id);
                        }
                        status.setIfRead(Constants.NO);
                        messageStatusDao.insert(status);
                    });
        }
        return 1;
    }
    
    @WriteTransactional
    public int delete(MessageStatusBO bo) {
        return messageStatusDao.delete(bo);
    }

    public void deleteByMessageId(String messageId) {
        messageStatusDao.deleteByMessageId(messageId);
    }

    @WriteTransactional
    public MessageStatusBO updateRead(MessageBO bo) {
        List<MessageStatusBO> dataList = messageStatusDao.queryByEmployee(bo.getId(), bo.getEmployeeId());
        MessageStatusBO statusBO;
        if (!dataList.isEmpty()) {
            statusBO = dataList.getFirst();
            statusBO.setIfRead(Constants.YES);
            statusBO.setReadTime(System.currentTimeMillis());
            messageStatusDao.updateRead(statusBO);
        } else {
            statusBO = new MessageStatusBO();
            statusBO.setId(UUID.getUUID());
            statusBO.setMessageId(bo.getId());
            statusBO.setEmployeeId(bo.getEmployeeId());
            statusBO.setIfRead(Constants.YES);
            statusBO.setReadTime(System.currentTimeMillis());
            messageStatusDao.insert(statusBO);
        }
        return statusBO;
    }
}
